export const deepClone = (obj, wm = new WeakMap()) => {
  if (typeof obj !== 'object' && obj !== null) {
    return obj
  }
  if (wm.get(obj)) {
    return wm.get(obj)
  }
  if (obj instanceof Function) {
    return function () {
      obj.call(this, ...arguments)
    }
  }
  if (obj instanceof Date) {
    return new Date(obj)
  }
  if (obj instanceof RegExp) {
    return new RegExp(obj.source, obj.flags)
  }
  if (obj instanceof Error) {
    return new Error(obj.message)
  }
  let res = Array.isArray(obj) ? [] : {}
  wm.set(obj, res)
  for (let k in obj) {
    if (obj[k] instanceof Object) {
      res[k] = deepClone(obj[k], wm)
    } else {
      res[k] = obj[k]
    }
  }
  return res
}